      1  import java.awt.Color;

      2  import java.io.File;

      3  import java.net.URL;

      4  import java.awt.geom.AffineTransform;

      5  import java.awt.image.AffineTransformOp;

      6  import java.awt.image.BufferedImage;

      7  import java.awt.image.BufferedImageOp;

      8  import java.awt.image.ColorModel;

      9  import java.awt.image.Raster;

     10  import java.awt.image.WritableRaster;

     11  import javax.imageio.ImageIO;

     12  import javax.swing.ImageIcon;

     13  import javax.swing.JFileChooser;

     14  import javax.swing.JFrame;

     15  import javax.swing.JLabel;

     16

     17  /**

     18   * This class allows you to view and edit pictures.

     19   */

     20  public class Picture

     21  {

     22     private String source;

     23     private JFrame frame;

     24     private JLabel label;

     25     private BufferedImage image;

     26

     27     /**

     28        Constructs a blank picture.

     29     */

     30     public Picture()

     31     {

     32        frame = new JFrame();

     33        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

     34        label = new JLabel("(No image)");

     35        frame.add(label);

     36        frame.pack();

     37        frame.setVisible(true);

     38     }

     39

     40     /**

     41        Gets the width of this picture.

     42        @return the width

     43      */

     44     public int getWidth() { return image.getWidth(); }

     45

     46     /**

     47        Gets the height of this picture.

     48        @return the height

     49      */

     50     public int getHeight() { return image.getHeight(); }

     51

     52     /**

     53        Loads a picture from a given source.

     54        @param source the image source. If the source starts

     55        with http://, it is a URL, otherwise, a filename.

     56      */

     57     public void load(String source)

     58     {

     59        try

     60        {

     61           this.source = source;

     62           BufferedImage img;

     63           if (source.startsWith("http://"))

     64              img = ImageIO.read(new URL(source).openStream());

     65           else

     66              img = ImageIO.read(new File(source));

     67

     68           setImage(img);

     69        }

     70        catch (Exception ex)

     71        {

     72           this.source = null;

     73           ex.printStackTrace();

     74        }

     75     }

     76

     77     /**

     78        Reloads this picture, undoing any manipulations.

     79      */

     80     public void reload()

     81     {

     82        load(source);

     83     }

     84

     85     /**

     86        Displays a file chooser for picking a picture.

     87      */

     88     public void pick()

     89     {

     90        JFileChooser chooser = new JFileChooser(".");

     91        if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)

     92        {

     93           load(chooser.getSelectedFile().getAbsolutePath());

     94        }

     95     }

     96

     97     /**

     98        Moves this picture by the given amount in x- and y-direction.

     99        @param dx the offset in the x-direction

    100        @param dy the offset in the y-direction

    101      */

    102     public void move(int dx, int dy)

    103     {

    104        BufferedImageOp op = new AffineTransformOp(

    105           AffineTransform.getTranslateInstance(dx, dy),

    106           AffineTransformOp.TYPE_BILINEAR);

    107        BufferedImage filteredImage

    108           = new BufferedImage(image.getWidth(), image.getHeight(),

    109              BufferedImage.TYPE_INT_ARGB);

    110        op.filter(image, filteredImage);

    111        setImage(filteredImage);

    112     }

    113

    114     /**

    115        Scales this picture to a new size. If the new size is smaller

    116        than the old size, the remainder is filled with transparent

    117        pixels. If it is larger, it is clipped.

    118        @param newWidth the new width of the picture

    119        @param newHeight the new height of the picture

    120     */

    121     public void scale(int newWidth, int newHeight)

    122     {

    123        double dx = newWidth * 1.0 / image.getWidth();

    124        double dy = newHeight * 1.0 / image.getHeight();

    125        BufferedImageOp op = new AffineTransformOp(

    126           AffineTransform.getScaleInstance(dx, dy),

    127           AffineTransformOp.TYPE_BILINEAR);

    128        BufferedImage filteredImage

    129           = new BufferedImage(image.getWidth(), image.getHeight(),

    130              BufferedImage.TYPE_INT_ARGB);

    131        op.filter(image, filteredImage);

    132        setImage(filteredImage);

    133     }

    134

    135     /**

    136        Adds a black border to the image.

    137        @param width the border width

    138     */

    139     public void border(int width)

    140     {

    141        for (int x = 0; x < width; x++)

    142        {

    143           for (int y = 0; y < image.getHeight(); y++)

    144           {

    145              setColorAt(x, y, Color.BLACK);

    146              setColorAt(image.getWidth() - 1 - x, y, Color.BLACK);

    147           }

    148        }

    149        for (int y = 0;  y < width; y++)

    150        {

    151           for (int x = width; x < image.getWidth() - width; x++)

    152           {

    153              setColorAt(x, y, Color.BLACK);

    154              setColorAt(x, image.getHeight() - 1 - y, Color.BLACK);

    155           }

    156        }

    157     }

    158

    159     /**

    160        Gets the color of a pixel.

    161        @param x the column index (between 0 and getWidth() - 1)

    162        @param y the row index (between 0 and getHeight() - 1)

    163        @return the color of the pixel at position (x, y)

    164     */

    165     public Color getColorAt(int x, int y)

    166     {

    167        Raster raster = image.getRaster();

    168        ColorModel model = image.getColorModel();

    169        int argb = model.getRGB(raster.getDataElements(x, y, null));

    170        return new Color(argb, true);

    171     }

    172

    173     /**

    174        Sets the color of a pixel.

    175        @param x the column index (between 0 and getWidth() - 1)

    176        @param y the row index (between 0 and getHeight() - 1)

    177        @param c the color for the pixel at position (x, y)

    178     */

    179     public void setColorAt(int x, int y, Color c)

    180     {

    181        WritableRaster raster = image.getRaster();

    182        ColorModel model = image.getColorModel();

    183        Object colorData = model.getDataElements(c.getRGB(), null);

    184        raster.setDataElements(x, y, colorData);

    185        label.repaint();

    186     }

    187

    188     private void setImage(BufferedImage image)

    189     {

    190        this.image = image;

    191        label.setIcon(new ImageIcon(image));

    192        label.setText("");

    193        label.setSize(image.getWidth(), image.getHeight());

    194        frame.pack();

    195     }

    196  }